﻿namespace NetFx.SMIL
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Reflection;
  using System.Reflection.Emit;

  using NetFx.AGIL;
  using NetFx.SMIL.Definitions;
  using NetFx.SMIL.References;

  //TODO: need to provide the full thoughts on the compilation.
  /// <summary>
  /// SmilCode 代码合成器。
  /// </summary>
  public class SmilCodeCompositor : OperationFormatResolver
  {
    #region Statics
    public static SmilCodeCompositor of(MethodBuilder method)
    {
      return new SmilCodeCompositor(method);
    }
    #endregion
    #region Fields
    /// <summary>
    /// 用于建立方法的构造器。
    /// </summary>
    protected MethodBuilder method = null;
    /// <summary>
    /// 用于生成代码的书写器。
    /// </summary>
    protected AgilCodeWriter writer = null;
    #endregion
    #region Properties
    /// <summary>
    /// 获取方法构造器。
    /// </summary>
    public virtual MethodBuilder Method
    {
      get
      {
        return this.method;
      }
    }
    public virtual AgilCodeWriter Writer
    {
      get
      {
        return this.writer;
      }
    }
    #endregion
    #region Constructors
    public SmilCodeCompositor(MethodBuilder method)
    {
      if (method == null) throw new ArgumentNullException("method can not be null!");

      this.writer = AgilGeneratorWriter.of(method);
    }
    #endregion
    #region Methods
    #region Composites
    public virtual bool Composite(List<SmilOperation> operations)
    {
      int index = 0;

      return this.Composite(operations, ref index);
    }
    public virtual bool Composite(List<SmilOperation> operations,ref int index)
    {
      if (operations != null)
      {
        this.Resolve(operations);

        for (index = 0; index < operations.Count; index++)
        {
          SmilOperation operation = operations[index];

          if (operation != null)
          {
            this.Composite(operation.UnderlyingAgil);
          }
        }
      }
      return false;
    }
    protected virtual void Composite(AgilOperation agil)
    {
      if (agil != null)
      {
        this.writer.Write(agil);
      }
    }
    #endregion
    #region Utils
    protected override void Dispose(bool disposing)
		{
      if (disposing)
			{
				this.writer.Dispose();
        this.writer = null;
        this.isDisposed = true;
      }
      base.Dispose(disposing);
    }
    #endregion
    #endregion
  }
}
